import { observable, action, makeObservable, runInAction, flow, ObservableMap } from 'mobx-miniprogram';
import { imApi } from '../../apis/im/index';
import { IMessage, IConversation, IGreetingStatus, MessageType, MessageStatus, IPeerContact } from '@/typings';

class IMStore {
  conversationList: IConversation[] = []; // 会话列表
  activeConversationMessages: IMessage[] = [];
  currentMessages: ObservableMap<string, IMessage[]> = observable.map<string, IMessage[]>();  // 按会话ID存储的聊天消息列表
  totalUnreadCount: number = 0; // 所有会话总未读数
  unreadCounts: { [conversationId: string]: number } = {}; // 各会话未读数映射
  // 当前活跃会话相关状态
  activeConversationId: string | null = null; // 当前正在查看的会话ID
  activeConversationPeerId: string | null = null; // 当前会话的对方UID
  activeConversationIsBlocked: boolean = false; // 当前会话对方是否被当前用户拉黑
  activeConversationIsVirtual: boolean = false; // 新增：当前会话对方是否是虚拟用户
  activeConversationPeerContact: IPeerContact | null = null; // 当前会话对方的联系方式
  hasMoreMessages: boolean = true; // 当前活跃会话是否有更多历史消息可加载
  isFetchingMessages: boolean = false; // 是否正在加载当前活跃会话的消息
  isFetchingConversations: boolean = false; // 是否正在加载会话列表
  constructor() {
    // 使用 makeObservable 替代装饰器
    makeObservable(this, {
      conversationList: observable,
      activeConversationMessages: observable,
      totalUnreadCount: observable,
      unreadCounts: observable,
      activeConversationId: observable,
      activeConversationPeerId: observable,
      activeConversationIsBlocked: observable,
      activeConversationIsVirtual: observable, // 声明为可观察
      activeConversationPeerContact: observable, // <--- 声明为可观察
      hasMoreMessages: observable,
      isFetchingMessages: observable,
      isFetchingConversations: observable,
      respondToContactRequest: action,
      reqContact: action, // <--- 新增 Action
      updateActiveConversationContact: action, // <--- 新增内部 Action
      setActiveConversation: action,
      fetchConversationList: action,
      fetchMessages: action,
      sendMessage: action,
      revokeMessage: action,
      addBlock: action,
      removeBlock: action,
      fetchUnreadCounts: action,
      clearConversationUnreadCount: action,
      clearAllUnreadCounts: action,
    });
  }

  // 动作 (action)
  /**
   * 设置当前活跃的会话。进入聊天页面时调用。
   * @param conversationId 会话ID
   * @param peerId 对方用户ID
   * @param isBlocked 对方是否被当前用户拉黑
   * @param initialGreetingStatus 初始打招呼状态
   * @param isVirtualPeer 对方是否是虚拟用户
   * @param peerContact 对方的联系方式 
   */
  setActiveConversation(
    conversationId: string | null,
    peerId: string | null,
    isBlocked: boolean,
    isVirtualPeer: boolean = false,
    peerContact: IPeerContact | null = null
  ) {
    this.activeConversationId = conversationId;
    this.activeConversationPeerId = peerId;
    this.activeConversationIsBlocked = isBlocked;
    this.activeConversationIsVirtual = isVirtualPeer; // 设置虚拟用户状态
    this.activeConversationPeerContact = peerContact;
    // 重置与新会话相关的状态
    this.hasMoreMessages = true; // 默认有更多消息，以便首次加载
    this.isFetchingMessages = false;

    // 移除了 start/stopChatPolling 的调用
  }

  // --- 会话列表相关操作 ---

  // 移除了 startConversationPolling 和 stopConversationPolling

  /**
   * 加载/刷新会话列表。
   * @param refresh true表示刷新（从头开始加载），false表示加载更多
   */
  async fetchConversationList(refresh: boolean = false) {
    if (this.isFetchingConversations) return;
    this.isFetchingConversations = true;

    try {
      const limit = 20;
      let skip = 0;
      let maxUpdateTime: number | undefined = undefined;

      if (!refresh && this.conversationList.length > 0) {
        maxUpdateTime = this.conversationList[this.conversationList.length - 1]?.updateTime;
      }

      const res = await imApi.getConversationList(limit, skip, maxUpdateTime);
      if (res.length === 0) return "没有消息"
      const newConversations = res.map(conv => ({
        conversation_id: conv.id,
        peer_uid: conv.peer_id,
        peer_nickname: conv.peer_nickname,
        peer_avatar: conv.peer_avatar,
        updateTime: conv.last_msg_create_time,
        lastMessage: {
          type: 'text',
          body: conv.last_msg_note
        },
        unreadCount: conv.unread_count,
        isBlockedByMe: conv.blocked,
        peerContact: conv.peer_contact || { phoneNumber: false, wx: false },
        isSystemConversation: ['system_notice_id', 'ad_message_id', 'order_message_id'].includes(conv.peer_uid),
        isVirtualPeer: ['system_notice_id', 'ad_message_id', 'order_message_id'].includes(conv.peer_uid)
      }));

      runInAction(() => {
        if (refresh) {
          this.conversationList = newConversations;
        } else {
          const existingConvIds = new Set(this.conversationList.map(c => c.conversation_id));
          const uniqueNewConversations = newConversations.filter(c => !existingConvIds.has(c.conversation_id));
          this.conversationList = [...this.conversationList, ...uniqueNewConversations];
        }
        this.conversationList.sort((a, b) => b.updateTime - a.updateTime);
      });

    } catch (error) {
      wx.showToast({
        title: "请检查网络",
        icon: "none"
      })
      console.error('Failed to fetch conversation list:', error);
    } finally {
      runInAction(() => {
        this.isFetchingConversations = false;
      });
    }
  }

  // --- 聊天消息相关操作 ---

  /**
     * 索取联系方式
     * @param requestType 'phone' | 'wx'
     */
  async reqContact(requestType: 'phone' | 'wx') {
    if (!this.activeConversationPeerId) return;

    // 构造请求消息体
    const requestText = `我希望能够获取你的${requestType === 'phone' ? '手机号码' : '微信'}，方便进一步联系。`;
    const messageBody = {
      requestType: requestType,
      text: requestText,
    };

    try {
      // 使用 sendMessage 发送一个特殊类型的消息
      // 注意：这里假设 sendMessage 内部已经处理了 to_uid, 这里我们只需要提供消息体和类型
      // 为了不影响原有的 sendMessage 流程，我们直接调用 imApi.sendMsg
      await this.sendMessage(this.activeConversationPeerId, messageBody, 'contact_request');
    } catch (error) {
      console.error('Failed to request contact info:', error);
      wx.showToast({ title: '请求发送失败', icon: 'none' });
    }
  }
  /**
   * (内部 Action) 更新当前活跃会话的联系方式
   * @param contactUpdate 部分联系方式信息
   */
  updateActiveConversationContact(contactUpdate: Partial<IPeerContact>) {
    if (!this.activeConversationId || !this.activeConversationPeerContact) return;

    // 更新当前页面的联系方式状态
    const newContactInfo = { ...this.activeConversationPeerContact, ...contactUpdate };
    this.activeConversationPeerContact = newContactInfo;

    // 同步更新会话列表中的联系方式，确保返回列表页时数据一致
    const convIndex = this.conversationList.findIndex(c => c.conversation_id === this.activeConversationId);
    if (convIndex > -1) {
      this.conversationList[convIndex].peerContact = newContactInfo;
      // 触发列表更新
      this.conversationList = [...this.conversationList];
    }
  }
  /**
     * (已重构) 响应联系方式请求。
     * 使用 sendMessage 发送一个 'contact_response' 类型的消息来代替独立的API调用。
     * @param msgId 请求消息的ID
     * @param decision 'approved' | 'denied'
     */
  async respondToContactRequest(msgId: string, decision: 'approved' | 'denied') {
    if (!this.activeConversationId || !this.activeConversationPeerId) {
      console.error("No active conversation to respond in.");
      return;
    }
    wx.showLoading({ title: '处理中...', mask: true });

    try {
      // 步骤 1: 立即更新本地UI状态以获得即时反馈
      let requestType: 'phone' | 'wx' | undefined;
      runInAction(() => {
        const messages = this.currentMessages.get(this.activeConversationId!);
        if (messages) {
          const msgIndex = messages.findIndex(m => m.msg_id === msgId);
          if (msgIndex > -1) {
            // 更新这条消息的状态，让按钮消失
            messages[msgIndex].requestStatus = decision;
            messages[msgIndex].isHandled = true; // 标记为已处理
            requestType = messages[msgIndex].parsedBody?.requestType; // 保存请求类型以备后用

            // 触发 MobX 更新
            const updatedMessages = [...messages];
            this.currentMessages.set(this.activeConversationId!, updatedMessages);
            if (this.activeConversationId) {
              this.activeConversationMessages = updatedMessages;
            }
          }
        }
      });

      // 步骤 2: 准备 'contact_response' 消息的 body
      // 这个消息主要用于机器间通信，通知后端和对方客户端
      const responsePayload = {
        decision: decision,
        originalMsgId: msgId, // 附上原始消息ID，便于对方客户端处理
        requestType: requestType // 附上请求类型，便于对方客户端更新对应的联系方式
      };

      // 步骤 3: 发送 'contact_response' 系统消息
      // 注意：这个 await 实际上是调用了 this.sendMessage。我们假设 sendMessage 内部处理了发送逻辑。
      // 这个消息不会在发送方显示，因为WXML中已经过滤了 'contact_response' 类型。
      await this.sendMessage(this.activeConversationPeerId, responsePayload, 'contact_response');
      wx.hideLoading();
      wx.showToast({ title: '操作成功', icon: 'none' });

    } catch (error) {
      wx.hideLoading();
      console.error('Failed to respond to contact request:', error);
      wx.showToast({ title: '操作失败，请重试', icon: 'none' });

      // 可选：如果操作失败，回滚UI状态
      runInAction(() => {
        const messages = this.currentMessages.get(this.activeConversationId!);
        if (messages) {
          const msgIndex = messages.findIndex(m => m.msg_id === msgId);
          if (msgIndex > -1) {
            messages[msgIndex].requestStatus = 'pending';
            messages[msgIndex].isHandled = false;
            this.currentMessages.set(this.activeConversationId!, [...messages]);
            this.activeConversationMessages = [...messages];
          }
        }
      });
    }
  }
  /**
   * 加载指定会话的消息列表。
   * @param conversationId 会话ID
   * @param isLoadMore true表示加载更多历史消息（追加到顶部），false表示刷新最新消息（覆盖或追加）
   * @param isPolling 此参数不再使用
   */
  fetchMessages = flow(function* (this: IMStore, conversationId: string, isLoadMore: boolean = false) { // 移除了 isPolling 参数
    const myCurrentUid = wx.getStorageSync('uid');
    if (!myCurrentUid) {
      console.warn('Current user UID not found in storage. Cannot fetch messages.');
      return;
    }

    if (this.isFetchingMessages) { // 移除了 isPolling 判断
      return;
    }

    this.isFetchingMessages = true; // 始终显示加载中提示
    wx.showLoading({ title: '加载消息中...', mask: true });


    try {
      let maxCreateTime: number | undefined;
      const currentMsgs = this.currentMessages.get(conversationId) || [];

      if (isLoadMore && currentMsgs.length > 0) {
        maxCreateTime = currentMsgs[0].createTime;
      }
      const res = yield imApi.getMsgList(conversationId, maxCreateTime);
      const filterRes = res.data.filter(item => !item.is_revoke)
      const processedNewMessages = filterRes.map(msg => {
        const baseMessage: IMessage = {
          msg_id: msg._id,
          conversation_id: msg.conversation_id,
          from_uid: msg.from_uid,
          to_uid: msg.to_uid,
          type: msg.type,
          body: msg.body,
          createTime: msg.create_time,
          isMyMessage: msg.from_uid === myCurrentUid,
          status: 'success' as MessageStatus,
          canRevoke: false, // 默认系统消息不可撤回
        };
        if (msg.type === 'contact_request') {
          try {
            baseMessage.requestStatus = msg.isHandled; // 简化处理，实际可能需要区分 approved 和 denied
          } catch (e) {
            console.error("Failed to parse contact_request body:", e);
            baseMessage.type = 'text';
            baseMessage.body = '[不支持的系统消息]';
          }
        } else {
          baseMessage.canRevoke = msg.from_uid === myCurrentUid;
        }
        return baseMessage;
      });
      this.hasMoreMessages = res.data.length === 20; // 假设 limit 为 20
      let newMessagesToAssign: IMessage[];
      if (isLoadMore) {
        const existingMsgIds = new Set(currentMsgs.map(m => m.msg_id));
        const uniqueNewMessages = processedNewMessages.filter(m => !existingMsgIds.has(m.msg_id));
        // 加载更多：新消息在前（因为是从旧到新排列，所以反转后prepend）
        newMessagesToAssign = [...uniqueNewMessages.reverse(), ...currentMsgs];
      } else {
        const existingMsgIds = new Set(currentMsgs.map(m => m.msg_id));
        const uniqueNewMessages = processedNewMessages.filter(m => !existingMsgIds.has(m.msg_id));
        newMessagesToAssign = [...currentMsgs, ...uniqueNewMessages];
      }
      this.currentMessages.set(conversationId, newMessagesToAssign);
      if (this.activeConversationId === conversationId) {
        this.activeConversationMessages = newMessagesToAssign;
      }
    } catch (error) {
      console.log(error)
      wx.showToast({ title: '加载消息失败', icon: 'none' })
    } finally {
      runInAction(() => {
        this.isFetchingMessages = false;
        wx.hideLoading();
      });
    }
  }.bind(this));

  /**
   * 发送消息。
   * @param to_uid 接收方UID
   * @param body 消息内容
   * @param type 消息类型
   */
  async sendMessage(to_uid: string, body: string, type: MessageType) {
    if (!this.activeConversationId) return;

    const myCurrentUid = wx.getStorageSync('uid');
    if (!myCurrentUid) {
      console.warn('Current user UID not found in storage. Cannot send message.');
      wx.showToast({ title: '用户未登录', icon: 'none' });
      return;
    }
    if (this.activeConversationIsBlocked) {
      wx.showToast({ title: '您已将对方拉黑，无法发送消息', icon: 'none' });
      return;
    }
    wx.showLoading({
      title: "发送中...",
      icon: "none"
    })
    try {
      const res = await imApi.sendMsg(to_uid, body, type);
      if (res.errCode === 0) {
        const msg = res.temp
        const newMessage: IMessage = {
          msg_id: msg._id,
          conversation_id: this.activeConversationId,
          from_uid: myCurrentUid,
          to_uid: to_uid,
          type: msg.type,
          body: msg.body,
          createTime: msg.create_time,
          status: 'success',
          isMyMessage: msg.from_uid == myCurrentUid,
          canRevoke: msg.from_uid == myCurrentUid,
          from_avatar: msg.avatar,
          from_nickname: msg.nickname,
        };
        let messages = this.currentMessages.get(this.activeConversationId) || [];
        messages.push(newMessage);
        this.currentMessages.set(this.activeConversationId, messages);
        if (this.activeConversationId === newMessage.conversation_id) {
          this.activeConversationMessages = messages.filter(i => i)
        }
      } else {
        wx.showToast({
          title: res.errMsg,
          icon: "none",
          duration: 2000
        })
      }
      if (type === "contact_request") {
        this.fetchConversationList()
      }
    } catch (error) {
      wx.hideLoading()
      console.error('Failed to send message:', error);
      wx.showToast({ title: '发送失败', icon: 'none' });
    }
  }

  /**
   * 撤回消息。
   */
  async revokeMessage(msgId: string) {
    if (!this.activeConversationId) return;

    const myCurrentUid = wx.getStorageSync('uid');
    if (!myCurrentUid) {
      console.warn('Current user UID not found in storage. Cannot revoke message.');
      return;
    }

    const messageToRevoke = this.activeConversationMessages.find(msg => msg.msg_id === msgId);

    if (!messageToRevoke || messageToRevoke.from_uid !== myCurrentUid) {
      wx.showToast({ title: '只能撤回自己发送的消息', icon: 'none' });
      return;
    }

    try {
      const res = await imApi.revokeMsg(msgId);
      if (res.errCode === 0) {
        runInAction(() => {
          const currentMsgs = this.currentMessages.get(this.activeConversationId!)!;
          const currentMsgss = currentMsgs.filter(msg => msg.msg_id !== msgId);
          this.currentMessages.set(this.activeConversationId, currentMsgss)
          if (this.activeConversationId) {
            this.activeConversationMessages = currentMsgss;
          }
        });
        wx.showToast({ title: '消息已撤回', icon: 'none' });
        this.fetchConversationList(true); // 刷新会话列表，确保最后一条消息状态更新
      } else {
        wx.showToast({ title: res.errMsg, icon: 'none' });
      }
    } catch (error) {
      console.error('Failed to revoke message:', error);
      wx.showToast({ title: '撤回失败', icon: 'none' });
    }
  }

  /**
   * 添加拉黑关系。
   */
  async addBlock(blockUid: string) {
    try {
      await imApi.addBlock(blockUid);
      runInAction(() => {
        this.activeConversationIsBlocked = true;
        wx.showToast({ title: '已拉黑该用户', icon: 'success' });
        const conv = this.conversationList.find(c => c.peer_uid === blockUid);
        if (conv) {
          conv.isBlockedByMe = true;
          this.conversationList = this.conversationList.filter(c => c.peer_uid !== blockUid);
          wx.navigateBack()
        }
      });
    } catch (error) {
      console.error('Failed to add block:', error);
      wx.showToast({ title: '拉黑失败', icon: 'none' });
    }
  }

  /**
   * 移除拉黑关系。
   */
  async removeBlock(blockUid: string) {
    try {
      await imApi.removeBlock(blockUid);
      runInAction(() => {
        this.activeConversationIsBlocked = false;
        wx.showToast({ title: '已解除拉黑', icon: 'success' });
        const conv = this.conversationList.find(c => c.peer_uid === blockUid);
        if (conv) {
          conv.isBlockedByMe = false;
          this.conversationList = [...this.conversationList];
        }
      });
    } catch (error) {
      console.error('Failed to remove block:', error);
      wx.showToast({ title: '解除拉黑失败', icon: 'none' });
    }
  }

  /**
   * 获取所有会话的未读数。
   */
  async fetchUnreadCounts() {
    try {
      const res = await imApi.getUnreadCount();
      if (res.data.unreadCount === 0) return;
      runInAction(() => {
        this.totalUnreadCount = res.data.unreadCount;
        this.unreadCounts = res.data.unreadCountObj;

        this.conversationList.forEach(conv => {
          conv.unreadCount = this.unreadCounts[conv.conversation_id] || 0;
        });
        this.conversationList = [...this.conversationList];
      });
    } catch (error) {
      console.error('Failed to fetch unread counts:', error);
    }
  }

  /**
   * 清除指定会话的未读数。
   */
  async clearConversationUnreadCount(conversationId: string) {
    try {
      await imApi.clearConversationUnreadCount(conversationId);
      runInAction(() => {
        if (this.unreadCounts[conversationId]) {
          this.totalUnreadCount -= this.unreadCounts[conversationId];
          delete this.unreadCounts[conversationId];
        }
        const conv = this.conversationList.find(c => c.conversation_id === conversationId);
        if (conv) {
          conv.unreadCount = 0;
          this.conversationList = [...this.conversationList];
        }
      });
    } catch (error) {
      console.error('Failed to clear conversation unread count:', error);
    }
  }

  /**
   * 清除所有会话的未读数（如果业务需要“全部已读”功能）。
   */
  async clearAllUnreadCounts() {
    try {
      await imApi.clearAllUnreadCount();
      runInAction(() => {
        this.totalUnreadCount = 0;
        this.unreadCounts = {};
        this.conversationList.forEach(conv => conv.unreadCount = 0);
        this.conversationList = [...this.conversationList];
      });
    } catch (error) {
      console.error('Failed to clear all unread counts:', error);
    }
  }
}

// 实例化并导出MobX Store
export const imStore = new IMStore();
